﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
using System.Net.Sockets;
using Spinnerets.Network.Instrumentation;
using System.Net.NetworkInformation;

namespace Spinnerets.Network.UnitTests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class ScannerTest
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ScannerTest"/> class.
        /// </summary>
        public ScannerTest() { }

        /// <summary>
        /// Gets or sets the test context.
        /// </summary>
        /// <value>The test context.</value>
        public TestContext TestContext { get; set; }

        [TestMethod]
        public void TestScanSubnet()
        {
            try
            {
                IPAddress startAddress, endAddress;
                //List<NetworkInterface> localInterfaces = NetworkInterface.GetAllNetworkInterfaces()
                //    .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback && i.OperationalStatus == OperationalStatus.Up).ToList();
                //IPHostEntry localHost
                startAddress = Dns.GetHostAddresses(Environment.MachineName)
                    .Where(a => a.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();

                IPAddress ipV6Address = IPAddress.Parse("fe80::221:70ff:fed5:249b"), ipV6EndAddress = IPAddress.Parse("fe80::221:70ff:fed5:24ef");

                // Use subnet of the localhost
                if (startAddress != null)
                {
                    byte[] localAddressBytes = startAddress.GetAddressBytes();

                    startAddress = new IPAddress(new byte[] { localAddressBytes[0], localAddressBytes[1], localAddressBytes[2], 0 });
                    endAddress = new IPAddress(new byte[] { localAddressBytes[0], localAddressBytes[1], localAddressBytes[2], 255 });
                }
                else
                {
                    startAddress = new IPAddress(new byte[] { 10, 137, 7, 0 });
                    endAddress = new IPAddress(new byte[] { 10, 137, 7, 255 });
                }

                NetworkScanner scanner = new NetworkScanner(startAddress, endAddress);
                scanner.DeviceFound += new EventHandler<DeviceFoundArgs>(scanner_DeviceFound);
                scanner.Execute();
            }
            catch (UnitTestAssertException) { throw; }
            catch (Exception ex)
            {
                Assert.Fail(ex.ToString());
            }
        }

        [TestMethod]
        public void TestScanSingle()
        {
            IPAddress startAddress, endAddress;

            startAddress = IPAddress.Parse("10.3.0.2");
            endAddress = startAddress;

            NetworkScanner scanner = new NetworkScanner(startAddress, endAddress);
            scanner.DeviceFound += new EventHandler<DeviceFoundArgs>(scanner_DeviceFound);
            scanner.Execute();
        }

        void scanner_DeviceFound(object sender, DeviceFoundArgs e)
        {
            if (e.Reply != null)
            {
                switch (e.Reply.Status)
                {
                    case IPStatus.Success:
                        TestContext.WriteLine("Discovered device {0} at {1} in {2}ms.", e.HostEntry.HostName, e.Reply.Address, e.Reply.RoundtripTime);
                        break;
                    default:
                        //TestContext.WriteLine("Response from {0} was {1}", e.Reply.Address, e.Reply.Status);
                        break;
                }
            }
        }

        [TestMethod]
        public void TestNetworkAddress()
        {
            IPHostEntry localHost = Dns.GetHostEntry(Environment.MachineName);
            IPAddress currentIpAddress = localHost.AddressList
                    .Where(a => a.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault(),
                ipV6Address = IPAddress.Parse("fe80::221:70ff:fed5:249b");

            NetworkAddress networkAddress = new NetworkAddress(currentIpAddress),
                compareAddress = new NetworkAddress(currentIpAddress);
            networkAddress++;

            networkAddress = new NetworkAddress(ipV6Address);
            networkAddress = new NetworkAddress(currentIpAddress.ToString());
            networkAddress = new NetworkAddress(ipV6Address.ToString());
        }
    }
}
